﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Shapes;

namespace config.view
{
    public partial class FrequencySet : UserControl
    {
        private List<Slider> frequencySliders;
        private List<TextBlock> valueDisplays;
        private List<double> centerFrequencies;

        // 添加频率范围参数
        private double minFrequency = 0;   // 最小频率 (Hz)
        private double maxFrequency = 100; // 最大频率 (Hz)

        public FrequencySet()
        {
            InitializeComponent();
            InitializeFrequencyControls();
            DrawResponseCurve();
        }

        private void InitializeFrequencyControls()
        {
            // 初始化频率滑块列表
            frequencySliders = new List<Slider>
            {
                Slider1, Slider2, Slider3,
                Slider4, Slider5, Slider6
            };

            valueDisplays = new List<TextBlock>
            {
                Value1, Value2, Value3,
                Value4, Value5, Value6
            };

            // 中心频率 - 根据您的需求调整为 10, 15, 25, 40, 60, 100
            centerFrequencies = new List<double> { 10, 15, 25, 40, 60, 100 };

            // 为所有滑块添加事件处理
            foreach (var slider in frequencySliders)
            {
                slider.ValueChanged += FrequencySlider_ValueChanged;
            }

            // 按钮事件
            ResetButton.Click += ResetButton_Click;
            ApplyButton.Click += ApplyButton_Click;
        }

        private void FrequencySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            Slider slider = sender as Slider;
            if (slider == null) return;

            // 更新对应的值显示
            int index = frequencySliders.IndexOf(slider);
            if (index >= 0 && index < valueDisplays.Count)
            {
                valueDisplays[index].Text = slider.Value.ToString("0.0");
            }

            // 重绘响应曲线
            DrawResponseCurve();
        }

        private void DrawResponseCurve()
        {
            ResponseCanvas.Children.Clear();

            double canvasWidth = ResponseCanvas.ActualWidth;
            double canvasHeight = ResponseCanvas.ActualHeight;

            if (canvasWidth <= 0 || canvasHeight <= 0) return;

            // 绘制背景网格
            DrawGrid(canvasWidth, canvasHeight);

            // 绘制样条曲线拟合的频率响应
            DrawSplineResponseCurve(canvasWidth, canvasHeight);

            // 绘制控制点
            DrawControlPoints(canvasWidth, canvasHeight);
        }

        private void DrawGrid(double width, double height)
        {
            // 水平网格线 (增益刻度)
            for (int i = 0; i <= 5; i++)
            {
                double y = height - (i / 5.0 * height);

                Line line = new Line
                {
                    X1 = 0,
                    X2 = width,
                    Y1 = y,
                    Y2 = y,
                    Stroke = new SolidColorBrush(Color.FromArgb(0x30, 0x88, 0x88, 0x88)),
                    StrokeThickness = 1
                };
                ResponseCanvas.Children.Add(line);

                // 增益标签
                TextBlock label = new TextBlock
                {
                    Text = i.ToString(),
                    Foreground = new SolidColorBrush(Color.FromArgb(0x80, 0xCC, 0xCC, 0xCC)),
                    FontSize = 10
                };
                Canvas.SetLeft(label, 5);
                Canvas.SetTop(label, y - 10);
                ResponseCanvas.Children.Add(label);
            }

            // 垂直网格线 (频率刻度) - 修改这里来调整频率间隔
            // 方法1: 使用对数间隔（推荐用于频率显示）
            //double[] logFreqTicks = GenerateLogFrequencyTicks(minFrequency, maxFrequency);
            //foreach (double freq in logFreqTicks)
            //{
            //    double x = FrequencyToXPosition(freq, width);

            //    Line line = new Line
            //    {
            //        X1 = x,
            //        X2 = x,
            //        Y1 = 0,
            //        Y2 = height,
            //        Stroke = new SolidColorBrush(Color.FromArgb(0x30, 0x88, 0x88, 0x88)),
            //        StrokeThickness = 1
            //    };
            //    ResponseCanvas.Children.Add(line);

            //    // 频率标签
            //    string freqLabel = FormatFrequencyLabel(freq);

            //    TextBlock label = new TextBlock
            //    {
            //        Text = freqLabel,
            //        Foreground = new SolidColorBrush(Color.FromArgb(0x80, 0xCC, 0xCC, 0xCC)),
            //        FontSize = 9,
            //        HorizontalAlignment = HorizontalAlignment.Center
            //    };
            //    Canvas.SetLeft(label, x - 15);
            //    Canvas.SetTop(label, height - 20);
            //    ResponseCanvas.Children.Add(label);
            //}

            // 方法2: 或者使用线性间隔（取消注释以下代码，并注释上面的对数间隔代码）

            double[] linearFreqTicks = GenerateLinearFrequencyTicks(minFrequency, maxFrequency);
            foreach (double freq in linearFreqTicks)
            {
                double x = FrequencyToXPosition(freq, width);

                Line line = new Line
                {
                    X1 = x,
                    X2 = x,
                    Y1 = 0,
                    Y2 = height,
                    Stroke = new SolidColorBrush(Color.FromArgb(0x30, 0x88, 0x88, 0x88)),
                    StrokeThickness = 1
                };
                ResponseCanvas.Children.Add(line);

                // 频率标签
                string freqLabel = FormatFrequencyLabel(freq);

                TextBlock label = new TextBlock
                {
                    Text = freqLabel,
                    Foreground = new SolidColorBrush(Color.FromArgb(0x80, 0xCC, 0xCC, 0xCC)),
                    FontSize = 9,
                    HorizontalAlignment = HorizontalAlignment.Center
                };
                Canvas.SetLeft(label, x - 15);
                Canvas.SetTop(label, height - 20);
                ResponseCanvas.Children.Add(label);
            }

        }

        // 生成对数频率刻度（推荐用于频率显示）
        private double[] GenerateLogFrequencyTicks(double minFreq, double maxFreq)
        {
            List<double> ticks = new List<double>();

            // 确定十的幂次范围
            int minPower = (int)Math.Floor(Math.Log10(minFreq));
            int maxPower = (int)Math.Ceiling(Math.Log10(maxFreq));

            // 在每个十的幂次之间添加刻度
            for (int power = minPower; power <= maxPower; power++)
            {
                double baseValue = Math.Pow(10, power);

                // 添加 1, 2, 5 倍数的刻度
                double[] multipliers = { 1, 2, 5 };
                foreach (double mult in multipliers)
                {
                    double freq = baseValue * mult;
                    if (freq >= minFreq && freq <= maxFreq)
                    {
                        ticks.Add(freq);
                    }
                }
            }

            return ticks.ToArray();
        }

        // 生成线性频率刻度
        private double[] GenerateLinearFrequencyTicks(double minFreq, double maxFreq)
        {
            List<double> ticks = new List<double>();

            // 确定合适的间隔
            double range = maxFreq - minFreq;
            double interval = CalculateNiceInterval(range, 6); // 大约6个刻度

            // 生成刻度
            double start = Math.Ceiling(minFreq / interval) * interval;
            for (double freq = start; freq <= maxFreq; freq += interval)
            {
                ticks.Add(freq);
            }

            return ticks.ToArray();
        }

        // 计算合适的刻度间隔
        private double CalculateNiceInterval(double range, int targetTickCount)
        {
            double roughInterval = range / targetTickCount;
            double magnitude = Math.Pow(10, Math.Floor(Math.Log10(roughInterval)));
            double fraction = roughInterval / magnitude;

            // 选择最接近的"好看"的分数
            double[] niceFractions = { 1, 2, 5, 10 };
            double closestFraction = niceFractions[0];
            foreach (double frac in niceFractions)
            {
                if (Math.Abs(frac - fraction) < Math.Abs(closestFraction - fraction))
                {
                    closestFraction = frac;
                }
            }

            return closestFraction * magnitude;
        }

        // 格式化频率标签
        private string FormatFrequencyLabel(double frequency)
        {
            if (frequency < 1000)
                return $"{frequency:0}Hz";
            else
                return $"{frequency / 1000:0.#}kHz";
        }

        private void DrawSplineResponseCurve(double width, double height)
        {
            // 准备控制点数据
            List<Point> controlPoints = new List<Point>();

            // 添加起始点 (低频延伸) - 使用新的频率范围
            double startFreq = minFrequency;
            double startGain = frequencySliders[0].Value;
            controlPoints.Add(new Point(
                FrequencyToXPosition(startFreq, width),
                GainToYPosition(startGain, height)
            ));

            // 添加控制点
            for (int i = 0; i < centerFrequencies.Count; i++)
            {
                double freq = centerFrequencies[i];
                double gain = frequencySliders[i].Value;

                controlPoints.Add(new Point(
                    FrequencyToXPosition(freq, width),
                    GainToYPosition(gain, height)
                ));
            }

            // 添加结束点 (高频延伸) - 使用新的频率范围
            double endFreq = maxFrequency;
            double endGain = frequencySliders[frequencySliders.Count - 1].Value;
            controlPoints.Add(new Point(
                FrequencyToXPosition(endFreq, width),
                GainToYPosition(endGain, height)
            ));

            // 使用样条曲线拟合
            List<Point> splinePoints = CalculateCatmullRomSpline(controlPoints, 50);

            // 绘制样条曲线
            Polyline curve = new Polyline
            {
                Stroke = new SolidColorBrush(Color.FromRgb(0x21, 0x96, 0xF3)),
                StrokeThickness = 2,
                Points = new PointCollection(splinePoints)
            };

            ResponseCanvas.Children.Add(curve);
        }

        private List<Point> CalculateCatmullRomSpline(List<Point> controlPoints, int segmentsPerPoint)
        {
            List<Point> result = new List<Point>();

            if (controlPoints.Count < 2)
                return result;

            // 添加第一个点
            result.Add(controlPoints[0]);

            // 对每对控制点之间进行插值
            for (int i = 0; i < controlPoints.Count - 1; i++)
            {
                Point p0, p1, p2, p3;

                // 计算控制点
                if (i == 0)
                {
                    // 第一个段，使用镜像点
                    p0 = controlPoints[0];
                    p1 = controlPoints[0];
                    p2 = controlPoints[1];
                    p3 = controlPoints[2];
                }
                else if (i == controlPoints.Count - 2)
                {
                    // 最后一个段，使用镜像点
                    p0 = controlPoints[i - 1];
                    p1 = controlPoints[i];
                    p2 = controlPoints[i + 1];
                    p3 = controlPoints[i + 1];
                }
                else
                {
                    // 中间段
                    p0 = controlPoints[i - 1];
                    p1 = controlPoints[i];
                    p2 = controlPoints[i + 1];
                    p3 = controlPoints[i + 2];
                }

                // 生成样条曲线上的点
                for (int j = 1; j <= segmentsPerPoint; j++)
                {
                    double t = j / (double)segmentsPerPoint;
                    Point point = CalculateCatmullRomPoint(t, p0, p1, p2, p3);
                    result.Add(point);
                }
            }

            return result;
        }

        private Point CalculateCatmullRomPoint(double t, Point p0, Point p1, Point p2, Point p3)
        {
            // Catmull-Rom 样条公式
            double t2 = t * t;
            double t3 = t2 * t;

            double x = 0.5 * ((2 * p1.X) +
                             (-p0.X + p2.X) * t +
                             (2 * p0.X - 5 * p1.X + 4 * p2.X - p3.X) * t2 +
                             (-p0.X + 3 * p1.X - 3 * p2.X + p3.X) * t3);

            double y = 0.5 * ((2 * p1.Y) +
                             (-p0.Y + p2.Y) * t +
                             (2 * p0.Y - 5 * p1.Y + 4 * p2.Y - p3.Y) * t2 +
                             (-p0.Y + 3 * p1.Y - 3 * p2.Y + p3.Y) * t3);

            return new Point(x, y);
        }

        private void DrawControlPoints(double width, double height)
        {
            for (int i = 0; i < centerFrequencies.Count; i++)
            {
                double freq = centerFrequencies[i];
                double gain = frequencySliders[i].Value;

                double x = FrequencyToXPosition(freq, width);
                double y = GainToYPosition(gain, height);

                // 控制点
                Ellipse point = new Ellipse
                {
                    Width = 10,
                    Height = 10,
                    Fill = GetFrequencyColor(freq),
                    Stroke = Brushes.White,
                    StrokeThickness = 1
                };

                Canvas.SetLeft(point, x - 5);
                Canvas.SetTop(point, y - 5);
                ResponseCanvas.Children.Add(point);

                // 增益值标签
                TextBlock valueLabel = new TextBlock
                {
                    Text = gain.ToString("0.0"),
                    Foreground = Brushes.White,
                    FontSize = 9,
                    Background = new SolidColorBrush(Color.FromArgb(0xCC, 0x33, 0x33, 0x33)),
                    Padding = new Thickness(3, 1, 3, 1)
                };

                Canvas.SetLeft(valueLabel, x - 12);
                Canvas.SetTop(valueLabel, y - 25);
                ResponseCanvas.Children.Add(valueLabel);
            }
        }

        private double FrequencyToXPosition(double frequency, double width)
        {
            // 使用新的频率范围：minFrequency 到 maxFrequency
            double logMin = (minFrequency);
            double logMax = (maxFrequency);
            double logFreq = (frequency);

            return (logFreq - logMin) / (logMax - logMin) * width;
        }

        private double GainToYPosition(double gain, double height)
        {
            // 增益范围：0到5
            return height - (gain / 5.0 * height);
        }

        private Brush GetFrequencyColor(double frequency)
        {
            // 根据频率返回不同的颜色
            // 根据您的频率范围调整颜色分段
            if (frequency <= 15) return new SolidColorBrush(Color.FromRgb(0x4C, 0xAF, 0x50));
            if (frequency <= 25) return new SolidColorBrush(Color.FromRgb(0x8B, 0xC3, 0x4A));
            if (frequency <= 40) return new SolidColorBrush(Color.FromRgb(0xCD, 0xDC, 0x39));
            if (frequency <= 60) return new SolidColorBrush(Color.FromRgb(0xFF, 0xC1, 0x07));
            return new SolidColorBrush(Color.FromRgb(0xF4, 0x43, 0x36));
        }

        private void ResetButton_Click(object sender, RoutedEventArgs e)
        {
            foreach (var slider in frequencySliders)
            {
                slider.Value = 1;
            }
        }

        private void ApplyButton_Click(object sender, RoutedEventArgs e)
        {
            string settings = "当前均衡器设置:\n";
            for (int i = 0; i < centerFrequencies.Count; i++)
            {
                string freqLabel = centerFrequencies[i] < 1000 ?
                    $"{centerFrequencies[i]}Hz" :
                    $"{centerFrequencies[i] / 1000:0.#}kHz";

                settings += $"{freqLabel}: {frequencySliders[i].Value:0.0}\n";
            }

            MyMessageBox.ShowQuestion(settings);
        }

        // 当Canvas大小改变时重绘曲线
        protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
        {
            base.OnRenderSizeChanged(sizeInfo);
            DrawResponseCurve();
        }
    }
}